package newcrunch.util;

import java.awt.Component;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import javax.swing.text.Element;
import jsyntaxpane.SyntaxDocument;
import jsyntaxpane.Token;
import jsyntaxpane.actions.ActionUtils;
import newcrunch.gui.NewCrunch;

/**
 * All other miscellaneous methods that do not belong to any class are put here.
 * @author ccadm
 */
public class Misc 
{
    public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
    
    public static NewCrunch getBaseGUI(Component comp)
    {
        while (comp != null && !(comp instanceof NewCrunch))
            comp = comp.getParent();
        
        return (comp instanceof NewCrunch) ? (NewCrunch)comp : null;
    }
    
    //credits to http://stackoverflow.com/questions/4159802/how-can-i-restart-a-java-application
    public static void restartApplication()
    {
        try {
            final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
            
            final File currentJar = new File(Misc.class.getProtectionDomain().getCodeSource().getLocation().toURI());

            /* is it a jar file? */
            if(!currentJar.getName().endsWith(".jar"))
                return;

            /* Build command: java -jar application.jar */
            final ArrayList<String> command = new ArrayList<String>();
            command.add(javaBin);
            command.add("-jar");
            command.add(currentJar.getPath());

            final ProcessBuilder builder = new ProcessBuilder(command);
            builder.start();
            System.exit(0);
        }
        catch (IOException ex) {
            Logging.log(ex);
        }
        catch (URISyntaxException ex) {
            Logging.log(ex);
        }
    }
    
    
    public static void setIntelligentKeyPair(final JEditorPane pane)
    {
        pane.addKeyListener(new KeyAdapter(){
            @Override
           public void keyTyped(KeyEvent evt)
           {
                SyntaxDocument doc = ActionUtils.getSyntaxDocument(pane);
                final int pos = pane.getCaretPosition();
                char item = evt.getKeyChar();
                switch (item)
                {
                    case ')':
                    case ']':
                        Token token = doc.getTokenAt(pos);
                        if (token != null && token.pairValue != 0) {
                            Token other = doc.getPairFor(token);
                            if (other != null) {
                                SwingUtilities.invokeLater(new Runnable(){
                                    @Override
                                    public void run()
                                    {
                                        String text = pane.getText();
                                        String front = text.substring(0, pos + 1);
                                        String back = (pos + 2 < text.length()) ? text.substring(pos + 2) : "";
                                        pane.setText(front + back);
                                        pane.setCaretPosition(pos + 1);
                                    }
                                });
                            }
                        }
                        break;
                }
           }
        });
    }
    
    /**
     * Converts the row number into the starting position of the character in that row.
     * Row number is zero based.
     * @param editor
     * @param row
     * @return 
     */
    public static int rowToPosition(JEditorPane editor, int row)
    {
        Element rootElement = editor.getDocument().getDefaultRootElement();
        
        if (row >= rootElement.getElementCount())
            return editor.getText().length();
        
        if (row < 0)
            return 0;
        
        return rootElement.getElement(row).getStartOffset();
    }
}
